﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Net;
using System.IO;
using System.Xml;
using MessageModel;

namespace Box51
{
    public class BoxProtocol
    {
        public string ServerAddress { get; set; }
        public string TaxNum { get; set; }
        private static string commKey;
        #region 发送数据
        private string sendData(string businessType, string data, int sendType)
        {
            try
            {
                if (string.IsNullOrEmpty(data))
                    throw new Exception("数据不能为空！");
                Encoding encoding = Encoding.GetEncoding("GB18030");
                string serverAddr = "http://" + ServerAddress + "/serverApp";
                HttpWebRequest hr = (HttpWebRequest)HttpWebRequest.Create(new Uri(serverAddr));
                #region 报文封装
                //报文格式
                string sData = "<?xml version=\"1.0\" encoding=\"GBK\"?>\r\n<FPXT_INPUT>\r\n<ID>" + businessType + "</ID>\r\n<DATA>" + CryptUtil.Crypt.Base64EnCrypt(data, encoding) + "</DATA>\r\n</FPXT_INPUT>";
                byte[] buffer = encryptData(sData, sendType, encoding);
                #endregion
                #region HTTP头
                hr.Headers.Clear();
                hr.ContentType = "application/octet-stream; Charset=gb18030";
                hr.Host = ServerAddress;
                hr.Method = "POST";
                //HTTP头，内容长度
                hr.ContentLength = buffer.Length;
                #endregion
                #region HTTP请求
                var reqStream = hr.GetRequestStream();
                reqStream.Write(buffer, 0, buffer.Length);
                //返回数据
                HttpWebResponse response = (HttpWebResponse)hr.GetResponse();
                if (response.GetResponseHeader("Content-Type") == "zjl")
                    throw new Exception("操作失败！服务器返回zjl");
                var resStream = response.GetResponseStream();
                buffer = new byte[response.ContentLength];
                resStream.Read(buffer, 0, (int)response.ContentLength);
                #endregion
                return decrypt(buffer);
            }
            catch (Exception)
            {

                throw;
            }
        }
        #endregion
        #region 加密要发送的数据
        private byte[] encryptData(string content, int crypType, Encoding encoding = null)
        {
            try
            {
                if (string.IsNullOrEmpty(content))
                    throw new Exception("原文不能为空！");
                encoding = encoding ?? Encoding.UTF8;
                byte[] crypMethod = encoding.GetBytes(crypType.ToString());
                byte[] crypData = new byte[] { };
                string prKey = "";
                if (crypType == 2)
                    prKey = commKey;
                else
                    prKey = (TaxNum + TaxNum + TaxNum + TaxNum).Substring(0, 24);
                crypData = CryptUtil.Crypt.Encrypt3DES(content, prKey, encoding);
                byte[] buffer = new byte[crypData.Length + crypMethod.Length];
                Array.Copy(crypMethod, 0, buffer, 0, crypMethod.Length);
                Array.Copy(crypData, 0, buffer, crypMethod.Length, crypData.Length);
                return buffer;
            }
            catch (Exception)
            {

                throw;
            }
        }
        #endregion
        #region 解密返回数据
        private string decrypt(byte[] pass)
        {
            try
            {
                if (null == pass || pass.Length < 1)
                    throw new Exception("数据不正确！");
                int crypType = Convert.ToInt32(pass[0]);
                byte[] crypData = new byte[pass.Length - 1];
                Array.Copy(pass, 1, crypData, 0, crypData.Length);
                string prKey = "";
                if (crypType == 2)
                    prKey = commKey;
                else
                    prKey = (TaxNum + TaxNum + TaxNum + TaxNum).Substring(0, 24);
                string retStr = CryptUtil.Crypt.Decrypt3DES(crypData, prKey, Encoding.GetEncoding("GB18030"));
                return retStr;
            }
            catch (Exception)
            {

                throw;
            }
        }
        #endregion
        #region 登录设备
        public LoginReturn LoginToDevice(string taxNum)
        {
            try
            {
                TaxNum = taxNum;
                LoginModel lm = new LoginModel
                {
                    DEVMAC = "",
                    DEVTYPE = "ATS-2100-G",
                    NAME = ""
                };
                string xmlData = sendData("DLSB", lm.ToString(), 3);
                if (string.IsNullOrEmpty(xmlData))
                    throw new Exception("参数不能为空！");
                XmlDocument xDoc = new XmlDocument();
                xmlData = xmlData.Replace("\0", "");
                xDoc.LoadXml(xmlData);
                XmlElement xl = xDoc.DocumentElement;
                var xList = xl.GetElementsByTagName("DATA"); ;
                xmlData = xList.Count < 1 ? "" : xList[0].InnerText;
                xmlData = CryptUtil.Crypt.Base64DeCrypt(xmlData, Encoding.GetEncoding("GB18030"));
                LoginReturn lr = new LoginReturn();
                lr.ResolveXML(xmlData);
                return lr;
            }
            catch (Exception)
            {
                throw;
            }
        }
        #endregion
        #region 3.1税控信息查询
        public SKQueryOutputModel GetTaxInfo(SKQueryRequestModel SKQuery, string taxNum, string DeviceSession)
        {
            try
            {
                TaxNum = taxNum;
                commKey = DeviceSession;
                //string xmlData = sendData("SKXXCX",SKQuery.ToString(), 2);
                string xmlData = File.ReadAllText(@"C:\app\51盒子\51API\test\3_1.xml", Encoding.GetEncoding("GB18030"));
                if (string.IsNullOrEmpty(xmlData))
                    throw new Exception("参数不能为空！");
                //XmlDocument xDoc = new XmlDocument();
                //xmlData = xmlData.Replace("\0", "");
                //xDoc.LoadXml(xmlData);
                //XmlElement xl = xDoc.DocumentElement;
                //var xList = xl.GetElementsByTagName("DATA"); ;
                //xmlData = xList.Count < 1 ? "" : xList[0].InnerText;
                //xmlData = CryptUtil.Crypt.Base64DeCrypt(xmlData, Encoding.GetEncoding("GB18030"));
                SKQueryOutputModel ret = new SKQueryOutputModel();
                ret.ResolveXml(xmlData);
                return ret;
            }
            catch (Exception)
            {
                throw;
            }
        }
        #endregion
        #region 3.2发票库存查询
        public TaxCardInvoiceStockQueryReturnModel GetTaxKC(TaxCardInvoiceStockQueryModel TaxKC, string taxNum, string DeviceSession)
        {
            try
            {
                TaxNum = taxNum;
                commKey = DeviceSession;
                //string xmlData = sendData("FPKCCX",TaxKC.ToString(), 2);
                string xmlData = File.ReadAllText(@"C:\app\51盒子\51API\test\3_2.xml", Encoding.GetEncoding("GB18030"));
                if (string.IsNullOrEmpty(xmlData))
                    throw new Exception("参数不能为空！");
                //XmlDocument xDoc = new XmlDocument();
                //xmlData = xmlData.Replace("\0", "");
                //xDoc.LoadXml(xmlData);
                //XmlElement xl = xDoc.DocumentElement;
                //var xList = xl.GetElementsByTagName("DATA"); ;
                //xmlData = xList.Count < 1 ? "" : xList[0].InnerText;
                //xmlData = CryptUtil.Crypt.Base64DeCrypt(xmlData, Encoding.GetEncoding("GB18030"));
                TaxCardInvoiceStockQueryReturnModel ret = new TaxCardInvoiceStockQueryReturnModel();
                ret.ResolveXml(xmlData);
                return ret;
            }
            catch (Exception)
            {
                throw;
            }
        }
        #endregion
        #region 3.3发票开具
        public InvoiceReturnModel InvoiceInfo(InvoiceIssueModel Invoice, string taxNum, string DeviceSession)
        {
            try
            {
                TaxNum = taxNum;
                commKey = DeviceSession;
                //string xmlData = sendData("FPKJ",Invoice.ToString(), 2);
                string xmlData = File.ReadAllText(@"C:\app\51盒子\51API\test\3_3.xml", Encoding.GetEncoding("GB18030"));
                if (string.IsNullOrEmpty(xmlData))
                    throw new Exception("参数不能为空！");
                //XmlDocument xDoc = new XmlDocument();
                //xmlData = xmlData.Replace("\0", "");
                //xDoc.LoadXml(xmlData);
                //XmlElement xl = xDoc.DocumentElement;
                //var xList = xl.GetElementsByTagName("DATA"); ;
                //xmlData = xList.Count < 1 ? "" : xList[0].InnerText;
                //xmlData = CryptUtil.Crypt.Base64DeCrypt(xmlData, Encoding.GetEncoding("GB18030"));
                InvoiceReturnModel ret = new InvoiceReturnModel();
                ret.ResolveXML(xmlData);
                return ret;
            }
            catch (Exception)
            {
                throw;
            }
        }
        #endregion
        #region 3.4发票查询
        public InvoiceQueryReturn GetFP(InvoiceQueryModel Inv, string taxNum, string DeviceSession)
        {
            try
            {
                TaxNum = taxNum;
                commKey = DeviceSession;
                //string xmlData = sendData("FPCX", Inv.ToString(), 2);
                string xmlData = File.ReadAllText(@"C:\app\51盒子\51API\test\3_4.xml", Encoding.GetEncoding("GB18030"));
                if (string.IsNullOrEmpty(xmlData))
                    throw new Exception("参数不能为空！");
                //XmlDocument xDoc = new XmlDocument();
                //xmlData = xmlData.Replace("\0", "");
                //xDoc.LoadXml(xmlData);
                //XmlElement xl = xDoc.DocumentElement;
                //var xList = xl.GetElementsByTagName("DATA"); ;
                //xmlData = xList.Count < 1 ? "" : xList[0].InnerText;
                //xmlData = CryptUtil.Crypt.Base64DeCrypt(xmlData, Encoding.GetEncoding("GB18030"));
                InvoiceQueryReturn ret = new InvoiceQueryReturn();
                ret.ResolveXML(xmlData);
                return ret;
            }
            catch (Exception)
            {
                throw;
            }
        }
        #endregion
        #region 3.5税收分类编码下载
        public TaxCodingReturn TaxCode(TaxCodingMessageModel tax, string taxNum, string DeviceSession)
        {
            try
            {
                TaxNum = taxNum;
                commKey = DeviceSession;
                //string xmlData = sendData("SSFLBMXZ", tax.ToString(), 2);
                string xmlData = File.ReadAllText(@"C:\app\51盒子\51API\test\3_5.xml", Encoding.GetEncoding("GB18030"));
                if (string.IsNullOrEmpty(xmlData))
                    throw new Exception("参数不能为空！");
                //XmlDocument xDoc = new XmlDocument();
                //xmlData = xmlData.Replace("\0", "");
                //xDoc.LoadXml(xmlData);
                //XmlElement xl = xDoc.DocumentElement;
                //var xList = xl.GetElementsByTagName("DATA"); ;
                //xmlData = xList.Count < 1 ? "" : xList[0].InnerText;
                //xmlData = CryptUtil.Crypt.Base64DeCrypt(xmlData, Encoding.GetEncoding("GB18030"));
                TaxCodingReturn ret = new TaxCodingReturn();
                ret.ResolveXML(xmlData);
                return ret;
            }
            catch (Exception)
            {
                throw;
            }
        }
        #endregion

    }
}
